package processing.test.mechaapp;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import processing.core.PApplet;
//import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;

public class GestureListener extends SimpleOnGestureListener{
	PApplet applet;
	Method singleTap;
	Method swipe;
	
	public final static int SWIPE_UP = 1;
	public final static int SWIPE_DOWN = 2;
	public final static int SWIPE_LEFT = 3;
	public final static int SWIPE_RIGHT = 4;
	
	private final static int MIN_SWIPE_DISTANCE = 100;
	private final static int MAX_SWIPE_DISTANCE = 350;
	private final static int MIN_SWIPE_VELOCITY = 50;
	
	public GestureListener(PApplet app){
		applet = app;
	}
		
	public void setSwipe(String name){
		try {
			swipe = applet.getClass().getMethod(name, int.class);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
	
	public void setSingleTap(String name){
		try {
			singleTap = applet.getClass().getMethod(name);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
	
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
		final float xDistance = Math.abs(e1.getX() - e2.getX());
		final float yDistance = Math.abs(e1.getY() - e2.getY());
		
		if(xDistance > this.MAX_SWIPE_DISTANCE || yDistance > this.MAX_SWIPE_DISTANCE) return false;
		
		velocityX = Math.abs(velocityX);
		velocityY = Math.abs(velocityY);
		boolean result = false;
		int direction = 0;
		
		if(velocityX > this.MIN_SWIPE_VELOCITY && xDistance > this.MIN_SWIPE_DISTANCE){
			if(e1.getX() > e2.getX())
				direction = this.SWIPE_LEFT;
			else
				direction = this.SWIPE_RIGHT;
			result = true;
		}else if(velocityY > this.MIN_SWIPE_VELOCITY && yDistance > this.MIN_SWIPE_DISTANCE){
			if(e1.getY() > e2.getY())
				direction = this.SWIPE_UP;
			else
				direction = this.SWIPE_DOWN;
			result = true;			
		}
		
		if(result){
			try {
				swipe.invoke(applet, direction);
			} catch (IllegalArgumentException e) {
				System.out.println("Illegal Argument Exception");
			} catch (IllegalAccessException e) {
				System.out.println("illegal access exception");
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		
		return result;		
	}
	
	public boolean onSingleTapUp(MotionEvent event){
		try {
			singleTap.invoke(applet);//invoke singleTap method
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		return true;
	}
	
}